#include "udp.h"
#include "etharp.h"
/*
***PCB分配内存
*/
struct udp_pcb *
udp_new(void){
 struct udp_pcb *pcb; 
    //为控制块分配空间
    pcb=(struct udp_pcb*)mymalloc(SRAM_IN,sizeof(struct udp_pcb));
    if(pcb ==NULL)
    {
      memset(pcb,0,sizeof(struct udp_pcb));
      return NULL; //内存申请失败
    }
   return pcb;
}
/*
***为PCB绑定属性
**如无IP地址和端口，填0；
*/
uint8_t 
udp_bind(struct udp_pcb *pcb,ip_addr_t *ipaddr,uint16_t port)
{
    if(pcb ==NULL)
        return NULL;//无控制块可配置
   ip_addr_set(&pcb->local_ip,ipaddr);
   pcb->local_port=port; 
  return 1;//绑定完成
}
/*
***为PCB块注册读取数据回调函数
*/
void
udp_recv(struct udp_pcb *pcb, udp_recv_fn recv)
{
    pcb->recv=recv;
}
/*
***Udp发送函数，无校验和
*/
void udp_send_to(struct netif *netif,struct pbuf *p,ip_addr_t *addr, uint16_t port)
{
   uint8_t udp_hdr[8];
   Pack_udp_hdr *udphdr =(Pack_udp_hdr *)udp_hdr;
   /*主机字节序，转换网络字节序*/
   udphdr->nSourPort =htons(netif->upcb->local_port);
   udphdr->nDestPort =htons(port);
   udphdr->nLength   =htons(sizeof(Pack_udp_hdr)+p->len);
   udphdr->nCheckSum =0;/*表示不使用UDP校验和，并非强制性*/
   /*偏移地址*/
   memcpy((uint8_t *)p->payload+(p->hdr_len-UDP_HLEN)
          ,udp_hdr,sizeof(Pack_udp_hdr));
   /*告诉Ip我要发送一个UDP数据包*/
   netif->flags =IP_PROTO_UDP;
   ip_output(netif,p,addr);
}

/*
***UDP解析数据函数
*/
void 
udp_input(struct netif *netif,struct pbuf *p)
{ 
    Pack_udp_hdr *udphdr;
    struct netif *lnetif;
    uint16_t port;
    //地址偏移
    udphdr=(Pack_udp_hdr *)((uint8_t *)p->payload+14/*ETH首部，一般情况固定不变*/+(netif->iphdrlen)*4);
    /*数据的长度*/
    p->len=htons(udphdr->nLength)-UDP_HLEN;
    /*远端口*/
    port=htons(udphdr->nDestPort);
    
    for(lnetif=netif;lnetif !=NULL;lnetif=lnetif->next){
        if(port ==lnetif->upcb->local_port){

        lnetif->upcb->remote_port=htons(udphdr->nSourPort);
        lnetif->upcb->recv(NULL,lnetif->upcb,//控制块
                           p,               //传输数据区
                           &lnetif->remotip_addr,
                           lnetif->upcb->remote_port);
      }
    }
p->payload=myfree(SRAM_IN,p->payload);
p=(struct pbuf *)myfree(SRAM_IN,p);
}
